package com.heima.ThreadPool.ForkJoin;


/**
 * @Author: Ethan Yankang
 * @Program: 面试必会代码
 * @Date: 2024-08-30 15:52
 **/


/*
    定义：
* ForkJoin是由JDK1.7之后提供的多线程并发处理框架。
* ForkJoin框架的基本思想是分而治之，将一个复杂的计算，按照设定的阈值分解成多个计算，然后将各个计算结果进行汇总。
* ForkJoinPool 是其核心，它管理工作线程，并帮助任务的拆分和合并。
*
*   适用场景:
1.大规模数据处理：如对大数组、大文件等进行并行处理。
2.递归计算：如快速排序、归并排序等，适合递归的算法。
    通过 ForkJoin 框架，可以显著提升并行计算的效率，特别是在多核 CPU 环境下。
*
*/


/*
 * @description 拆分与合并的过程类
 * @params
 * @return
 */
public class RecursiveTask extends java.util.concurrent.RecursiveTask<Long> {
    private static final int THRESHOLD=10000;//拆分阈值，达到这个阈值才进行计算，充分利用CPU效率
    private long[] array;
    private int start;
    private int end;
    private static int count=0;

    public RecursiveTask(long[] array, int start, int end) {
        this.array = array;
        this.end = end;
        this.start = start;
    }

    /*
     * @description 这是递归计算里面的默认方法，译名为计算
     * @params
     * @return
     */

    @Override
    protected Long compute() {
        if(end-start<=THRESHOLD){//粒度不超过1W就直接累加
            System.out.println("粒度小于1W了，直接进入CPU计算");
            long sum=0;
            for (int i = start; i < end; i++) {
                sum+=array[i];
            }
            return sum;
        }else {//粒度大于1W的时候就继续拆分
            System.out.println("粒度超过1W，继续划分成两半------"+count++);
            int middle = start + ((end - start) >> 1);//防止溢出
            RecursiveTask leftTask = new RecursiveTask(array, start, middle);
            RecursiveTask rifhtTask = new RecursiveTask(array, middle, end);

//            执行子任务
            leftTask.fork();
            rifhtTask.fork();

//            合并子任务
            Long leftResult = leftTask.join();
            Long rightResult = rifhtTask.join();

//            返回合并结果
            return leftResult + rightResult;
        }
    }
}
